﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using YABE.Validators;

namespace YABE.Models
{
    public partial class Comment : IRuleEntity
    {
        //to mockout db connection
        public ICommentDL commentDL{get;set;}
        
        #region Implementation of IRuleEntity

        public List<RuleViolation> GetRuleViolations()
        {
            List<RuleViolation> validationIssues = new List<RuleViolation>();
            
            RuleViolation AuthorValidation = CheckAuthorNotEmpty();
            if (AuthorValidation != null)
                validationIssues.Add(AuthorValidation);
            
            RuleViolation EmailValidation = ValidateEmailNotNull();
            if (EmailValidation != null)
                validationIssues.Add(EmailValidation);

            RuleViolation EmailFormatValidation = ValidateEmailFormat();
            if (EmailFormatValidation != null)
                validationIssues.Add(EmailFormatValidation);

            RuleViolation CommentsEmptyValidation = CheckCommentsNotEmpty();
            if (CommentsEmptyValidation != null)
                validationIssues.Add(CommentsEmptyValidation);

            RuleViolation commentorFrequencyValidation = CheckCommentorFrequency();
            if (commentorFrequencyValidation != null)
                validationIssues.Add(commentorFrequencyValidation);

            return validationIssues;
        }
        //Email cant be null
        public RuleViolation ValidateEmailNotNull()
        {
            RuleViolation EmailValidation = null;
            
            if(String.IsNullOrEmpty(this.Email)|| (this.Email.Trim().Length==0))
            {
                EmailValidation = new RuleViolation("EmailNull",String.Empty,Resources.ErrorMessages.EmailIsNull);
            }
            return EmailValidation;
        }
        //Email should have valid format
        public RuleViolation ValidateEmailFormat()
        {
            RuleViolation EmailValidation = null;
            if(String.IsNullOrEmpty(this.Email))
            {
                EmailValidation = new RuleViolation("EmailPattern",String.Empty,Resources.ErrorMessages.EmailPattern);
                return EmailValidation;
            }
            string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
                                 @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                                 @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
            Regex regex = new Regex(strRegex);
            if(!regex.IsMatch(this.Email))
                EmailValidation = new RuleViolation("EmailPattern",this.Email,Resources.ErrorMessages.EmailPattern);
            return EmailValidation;
        }
        //author cant be null
        public RuleViolation CheckAuthorNotEmpty()
        {
            RuleViolation AuthorValidation = null;
            if(String.IsNullOrEmpty(this.Author)|| (this.Author.Trim().Length==0))
            {
                AuthorValidation = new RuleViolation("AuthorEmpty",String.Empty,Resources.ErrorMessages.AuthorEmpty);
            }
            return AuthorValidation;
        }
        //comments cant be null
        public RuleViolation CheckCommentsNotEmpty()
        {
            RuleViolation validateCommentsNotEmpty = null;
            if((String.IsNullOrEmpty(this.Comments) ) || (this.Comments.Trim().Length==0))
                validateCommentsNotEmpty = new RuleViolation("CommentsEmpty",string.Empty,Resources.ErrorMessages.CommentsEmpty);

            return validateCommentsNotEmpty;
        }
        //same commentor cant comment before waiting 30seconds
        //commentor id is checked by IP address
        public RuleViolation CheckCommentorFrequency()
        {
            RuleViolation commentorFrequencyValidation = null;
            string CommentorIP = this.ClientIP;
            //check if any other comments from this ip order by datetime take 1
            //below interface checking is done to ease unit testing
            if (this.commentDL == null)
                commentDL = new YABE.Models.CommentDL();
            Comment commentorLatestComment = commentDL.GetLatestCommentByCommentor(this.ClientIP);
            if (commentorLatestComment == null)
                return commentorFrequencyValidation;

            DateTime dateTimeForLatestComment = commentorLatestComment.Created;
            TimeSpan timeDifference = DateTime.Now.Subtract(dateTimeForLatestComment);
            TimeSpan allowedTimeSpan = new TimeSpan(0,0,0,30);//this magic number could be moved to config
            if(timeDifference.TotalSeconds<allowedTimeSpan.TotalSeconds)
                commentorFrequencyValidation = new RuleViolation("FrequentCommentor",timeDifference.TotalSeconds,
                    Resources.ErrorMessages.FrequentCommentor);
            return commentorFrequencyValidation;
        }

        #endregion
    }
}
